import { AbstractParser, ParserOptions, ParseContext } from './BaseParser';
import { ExtractionTask, ExtractionResult } from '../types';
import * as xml2js from 'xml2js';

export class AndroidParser extends AbstractParser {
  private xmlParser: xml2js.Parser;

  constructor(options: ParserOptions) {
    super(options);
    this.xmlParser = new xml2js.Parser({
      explicitArray: false,
      mergeAttrs: true,
      normalize: true,
      normalizeTags: true,
      trim: true
    });
  }

  /**
   * 解析Android资源文件
   * @param content 文件内容
   * @param context 解析上下文
   */
  public async parse(content: string, context: ParseContext): Promise<ExtractionResult> {
    try {
      // 验证内容
      if (this.shouldIgnore(content)) {
        return this.createEmptyResult(context.task.taskId);
      }

      // 解析XML
      const result = await this.xmlParser.parseStringPromise(content);

      // 提取翻译键
      const translations = await this.extractTranslations(result, context);

      // 创建结果
      return {
        taskId: context.task.taskId,
        status: 'success',
        startTime: new Date().toISOString(),
        endTime: new Date().toISOString(),
        statistics: {
          totalFiles: 1,
          processedFiles: 1,
          extractedKeys: Object.keys(translations).length,
          errors: 0,
          processingTime: 0
        },
        translations,
        analysis: {
          coverage: {
            overall: 0,
            byLanguage: {},
            byModule: {},
            missingKeys: [],
            redundantKeys: []
          },
          usage: {
            highFrequency: [],
            lowFrequency: [],
            unusedKeys: []
          },
          modules: {},
          quality: {
            duplicates: [],
            namingIssues: [],
            contextIssues: []
          }
        },
        errors: [],
        suggestions: []
      };

    } catch (error) {
      return {
        taskId: context.task.taskId,
        status: 'failed',
        startTime: new Date().toISOString(),
        endTime: new Date().toISOString(),
        statistics: {
          totalFiles: 1,
          processedFiles: 0,
          extractedKeys: 0,
          errors: 1,
          processingTime: 0
        },
        translations: [],
        analysis: {
          coverage: {
            overall: 0,
            byLanguage: {},
            byModule: {},
            missingKeys: [],
            redundantKeys: []
          },
          usage: {
            highFrequency: [],
            lowFrequency: [],
            unusedKeys: []
          },
          modules: {},
          quality: {
            duplicates: [],
            namingIssues: [],
            contextIssues: []
          }
        },
        errors: [{
          file: context.filePath,
          message: (error as Error).message,
          stack: (error as Error).stack,
          severity: 'error'
        }],
        suggestions: []
      };
    }
  }

  /**
   * 提取翻译键
   * @param result XML解析结果
   * @param context 解析上下文
   */
  private async extractTranslations(result: any, context: ParseContext): Promise<ExtractionResult['translations']> {
    const translations: ExtractionResult['translations'] = {};

    // 遍历resources节点
    if (result.resources && result.resources.string) {
      const strings = Array.isArray(result.resources.string) 
        ? result.resources.string 
        : [result.resources.string];

      for (const str of strings) {
        const key = str.$?.name;
        if (!key || !this.isValidKey(key)) {
          continue;
        }

        const value = str._;
        if (!value || !this.isValidValue(value)) {
          continue;
        }

        // 提取注释
        const comment = str.$?.comment || '';
        const fileContext = this.extractContext(result.resources.string, 0, 0);

        // 创建翻译键信息
        translations[key] = {
          source: value,
          context: fileContext,
          module: this.getModuleFromPath(context.filePath),
          tags: this.extractTags(comment),
          occurrences: [{
            file: context.filePath,
            line: 0,
            column: 0,
            context: fileContext,
            scope: 'global',
            function: '',
            class: ''
          }],
          frequency: 1,
          lastUsed: new Date().toISOString(),
          translations: {
            [context.task.languages[0]]: {
              value,
              source: 'android',
              lastModified: new Date().toISOString(),
              status: 'valid',
              quality: 1,
              comments: comment ? [comment] : []
            }
          },
          metadata: {
            createdAt: new Date().toISOString(),
            createdBy: 'system',
            lastModified: new Date().toISOString(),
            modifiedBy: 'system',
            version: context.task.version,
            platform: ['android'],
            status: 'active'
          },
          analysis: {
            complexity: this.calculateComplexity(value),
            risk: this.assessRisk(value),
            suggestions: this.generateSuggestions(value),
            relatedKeys: [],
            dependencies: []
          }
        };
      }
    }

    return translations;
  }

  /**
   * 从路径获取模块名
   * @param filePath 文件路径
   */
  private getModuleFromPath(filePath: string): string {
    const parts = filePath.split('/');
    const resIndex = parts.indexOf('res');
    if (resIndex > 0) {
      return parts[resIndex - 1];
    }
    return 'unknown';
  }

  /**
   * 从注释中提取标签
   * @param comment 注释内容
   */
  private extractTags(comment: string): string[] {
    const tags: string[] = [];
    const tagRegex = /@(\w+)/g;
    let match;

    while ((match = tagRegex.exec(comment)) !== null) {
      tags.push(match[1]);
    }

    return tags;
  }

  /**
   * 计算复杂度
   * @param value 翻译值
   */
  private calculateComplexity(value: string): number {
    let complexity = 0;
    
    // 检查占位符数量
    const placeholderRegex = /%[0-9]*[sd]/g;
    const placeholders = value.match(placeholderRegex) || [];
    complexity += placeholders.length;

    // 检查HTML标签
    const htmlRegex = /<[^>]+>/g;
    const htmlTags = value.match(htmlRegex) || [];
    complexity += htmlTags.length;

    // 检查特殊字符
    const specialChars = value.match(/[&<>]/g) || [];
    complexity += specialChars.length;

    return complexity;
  }

  /**
   * 评估风险等级
   * @param value 翻译值
   */
  private assessRisk(value: string): 'high' | 'medium' | 'low' {
    const complexity = this.calculateComplexity(value);
    
    if (complexity > 5) {
      return 'high';
    } else if (complexity > 2) {
      return 'medium';
    }
    
    return 'low';
  }

  /**
   * 生成改进建议
   * @param value 翻译值
   */
  private generateSuggestions(value: string): string[] {
    const suggestions: string[] = [];

    // 检查占位符格式
    const placeholderRegex = /%[0-9]*[sd]/g;
    const placeholders = value.match(placeholderRegex) || [];
    if (placeholders.length > 0) {
      suggestions.push('Consider using named placeholders for better maintainability');
    }

    // 检查HTML标签
    const htmlRegex = /<[^>]+>/g;
    const htmlTags = value.match(htmlRegex) || [];
    if (htmlTags.length > 0) {
      suggestions.push('Consider using text styling attributes instead of HTML tags');
    }

    // 检查特殊字符
    const specialChars = value.match(/[&<>]/g) || [];
    if (specialChars.length > 0) {
      suggestions.push('Consider using HTML entities for special characters');
    }

    return suggestions;
  }

  /**
   * 创建空结果
   * @param taskId 任务ID
   */
  private createEmptyResult(taskId: string): ExtractionResult {
    return {
      taskId,
      status: 'success',
      startTime: new Date().toISOString(),
      endTime: new Date().toISOString(),
      statistics: {
        totalFiles: 1,
        processedFiles: 0,
        extractedKeys: 0,
        errors: 0,
        processingTime: 0
      },
      translations: [],
      analysis: {
        coverage: {
          overall: 0,
          byLanguage: {},
          byModule: {},
          missingKeys: [],
          redundantKeys: []
        },
        usage: {
          highFrequency: [],
          lowFrequency: [],
          unusedKeys: []
        },
        modules: {},
        quality: {
          duplicates: [],
          namingIssues: [],
          contextIssues: []
        }
      },
      errors: [],
      suggestions: []
    };
  }
} 